import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;

import java.util.ArrayList;
import java.util.Stack;

public class AnalyseTable {
    private Node treeNode;
    private Stack<SymbolTable> tables;
    private ArrayList<Pairs> error;

    public AnalyseTable(Node treeNode) {
        this.treeNode = treeNode;
        this.tables = new Stack<>();
        this.error = new ArrayList<>();
    }

    public ArrayList<Pairs> getError() {
        return error;
    }

    public Pairs containsIdent(String token) {
        Pairs result = null;
        for (SymbolTable i : tables) {
            if (i.tableMap.containsKey(token)) {
                result =  i.tableMap.get(token);
            }
        }
        return result;
    }

    public void buildTable(Node node) {
        if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("CompUnit")) {
            SymbolTable table = new SymbolTable();
            tables.push(table);
        }
        if (node.getChildren() != null) {
            for (Node i : node.getChildren()) {
                if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                    if (i.getPair().getKind().equals(Pairs.Kind.BREAKTK) || i.getPair().getKind().equals(Pairs.Kind.CONTINUETK)) {
                        if (!tables.peek().isCircle()) {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "m");
                            error.setLine(i.getPair().getLine());
                            this.error.add(error);
                        }
                    } /*else if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("Block") && i.getPair().getKind().equals(Pairs.Kind.RBRACE)) {
                        tables.pop();
                    }*/
                } else {
                    if (i.getPair().getToken().equals("Decl")) {
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("FuncDef")) {
                        if (i.getPair().getLine() == 55) {
                            int flag = 1;
                        }
                        insertTableFunc(i);
                    } else if (i.getPair().getToken().equals("ConstDecl")) {
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("ConstDef")) {
                        if (i.getPair().getLine() == 73) {
                            int flag = 1;
                        }
                        insertTableVal(i);
                    } else if (i.getPair().getToken().equals("ConstInitVal")) {
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("VarDecl")) {
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("VarDef")) {
                        insertTableVar(i);
                    } else if (i.getPair().getToken().equals("MainFuncDef")) {
                        Pairs pairs = new Pairs(Pairs.Kind.FUNC, i.getChildren().get(1).getPair().getToken(), "int", i.getChildren().get(1).getPair().getLine());
                        if (tables.peek().tableMap.containsKey(pairs.getToken())) {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
                            error.setLine(pairs.getLine());
                            this.error.add(error);
                        }
                        tables.peek().addPair(pairs);
                        for (Node j : i.getChildren()) {
                            if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Block")) {
                                SymbolTable table = new SymbolTable();
                                table.setType("int");
                                tables.push(table);
                                buildTable(j);
                                if (j.getChildren().size() > 2) {
                                    if (!j.getChildren().get(j.getChildren().size() - 2).getChildren().get(0).getChildren().get(0).getPair().getKind().equals(Pairs.Kind.RETURNTK)) {
                                        Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                        error.setLine(j.getChildren().get(j.getChildren().size() - 1).getPair().getLine());
                                        this.error.add(error);
                                    }
                                } else if (j.getChildren().size() == 2) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                    error.setLine(j.getChildren().get(j.getChildren().size() - 1).getPair().getLine());
                                    this.error.add(error);
                                }
                                tables.pop();
                            }
                        }
                        // buildTable(i);
                    } else if (i.getPair().getToken().equals("Block")) {
                        if (i.getPair().getLine() == 354) {
                            int falg = 1;
                        }
                        SymbolTable table = new SymbolTable();
                        if (tables.peek().isCircle() || tables.peek().isInt() || tables.peek().isVoid()) {
                            table.setType(tables.peek().getType());
                        }
                        tables.push(table);
                        buildTable(i);
                        /*if (i.getChildren().size() > 2) {
                            if (!i.getChildren().get(i.getChildren().size() - 2).getChildren().get(0).getPair().getKind().equals(Pairs.Kind.RETURNTK)) {
                                if (!tables.peek().isVoid() && !tables.peek().isSimple() && !tables.peek().isCircle()) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                    error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                                    this.error.add(error);
                                }
                            }
                        } else if (i.getChildren().size() == 2) {
                            if (!tables.peek().isVoid() && !tables.peek().isSimple() && !tables.peek().isCircle()) {
                                Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                                this.error.add(error);
                            }
                        }*/
                        tables.pop();
                    } else if (i.getPair().getToken().equals("BlockItem")) {
                        if (i.getPair().getLine() == 133) {
                            int flag = 1;
                        }
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("Stmt")) {
                        buildTableStmt(i);
                    } else if (i.getPair().getToken().equals("LVal")) {
                        processLVal(i);
                    } else if (i.getPair().getToken().equals("Cond")) {
                        buildTable(i);
                    } else if (i.getPair().getToken().equals("Exp")) {
                        buildTableExp(i);
                    } else if (i.getPair().getToken().equals("ConstExp")) {
                        buildTableExp(i.getChildren().get(0));
                    }
                }
            }
        }
    }

    public void insertTableFunc(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.FUNC, node.getChildren().get(1).getPair().getToken(), node.getChildren().get(1).getPair().getLine());
        if (pairs.getLine() == 130) {
            int flag = 1;
        }
        ArrayList<Pairs> paramList = new ArrayList<>();
        if (tables.peek().tableMap.containsKey(pairs.getToken())) {
            Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
            error.setLine(pairs.getLine());
            this.error.add(error);
        } else {
            tables.peek().addPair(pairs);
        }
            /*SymbolTable table = new SymbolTable();
            tables.push(table);*/
        SymbolTable table = new SymbolTable();
        tables.push(table);
        if (tables.peek().isCircle() || tables.peek().isInt() || tables.peek().isVoid()) {
            table.setType(tables.peek().getType());
        }
        for (Node i : node.getChildren()) {
            if (i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                if (i.getPair().getToken().equals("FuncType")) {
                    Node j = i.getChildren().get(0);
                    if (j.getPair().getKind().equals(Pairs.Kind.INTTK)) {
                        pairs.setType("int");
                        tables.peek().setType("int");
                    } else {
                        pairs.setType("void");
                        tables.peek().setType("void");
                    }
                } else if (i.getPair().getToken().equals("FuncFParams")) {
                    if (i.getPair().getLine() == 130) {
                        int flag = 1;
                    }
                    for (Node j : i.getChildren()) {
                        if (j.getPair().getToken().equals("FuncFParam")) {
                            if (j.getChildren().size() > 4) {
                                Pairs param = new Pairs(Pairs.Kind.ARRAY_VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine(), 2);
                                if (tables.peek().tableMap.containsKey(param.getToken())) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
                                    error.setLine(param.getLine());
                                    this.error.add(error);
                                } else {
                                    tables.peek().addPair(param);
                                    paramList.add(param);
                                }
                            } else if (j.getChildren().size() == 2) {
                                Pairs param = new Pairs(Pairs.Kind.VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine());
                                if (tables.peek().tableMap.containsKey(param.getToken())) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
                                    error.setLine(param.getLine());
                                    this.error.add(error);
                                } else {
                                    tables.peek().addPair(param);
                                    paramList.add(param);
                                }
                            } else {
                                Pairs param = new Pairs(Pairs.Kind.ARRAY_VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine(), 1);
                                if (tables.peek().tableMap.containsKey(param.getToken())) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
                                    error.setLine(param.getLine());
                                    this.error.add(error);
                                } else {
                                    tables.peek().addPair(param);
                                    paramList.add(param);
                                }
                            }
                        }
                    }
                } else if (i.getPair().getToken().equals("Block")) {
                    pairs.setParams(paramList);
                    if (i.getPair().getLine() == 130) {
                        int flag = 1;
                    }
                    buildTable(i);
                    if (i.getPair().getLine() == 354) {
                        int flag = 1;
                    }
                    if (i.getChildren().size() > 2) {
                        if (!i.getChildren().get(i.getChildren().size() - 2).getChildren().get(0).getChildren().get(0).getPair().getKind().equals(Pairs.Kind.RETURNTK)) {
                            if (!tables.peek().isSimple() && !tables.peek().isVoid() && !tables.peek().isCircle()) {
                                Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                                this.error.add(error);
                            }
                        }
                    } else if (i.getChildren().size() == 2) {
                        if (!tables.peek().isVoid() && !tables.peek().isSimple() && !tables.peek().isCircle()) {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                            error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                            this.error.add(error);
                        }
                    }
                    tables.pop();
                }
            }
        }

    }

    public void insertTableVal(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.VAL, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
        if (pairs.getLine() == 133) {
            int flag = 1;
        }
        if (tables.peek().tableMap.containsKey(pairs.getToken())) {
            Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
            error.setLine(pairs.getLine());
            this.error.add(error);
        } else {
            tables.peek().addPair(pairs);
            for (Node i : node.getChildren()) {
                if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                    if (i.getPair().getKind().equals(Pairs.Kind.LBRACK)) {
                        pairs.setKind(Pairs.Kind.ARRAY_VAL);
                        pairs.setDim(pairs.getDim() + 1);
                    }
                } else {
                    if (i.getPair().getToken().equals("ConstExp")) {
                        buildTableExp(i);
                    } else if (i.getPair().getToken().equals("ConstInitVal")) {
                        buildTable(i);
                    }
                }
            }
            tables.peek().addPair(pairs);
        }
    }

    public void insertTableVar(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.VAR, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
        if (pairs.getLine() == 6) {
            int flag = 1;
        }
        if (tables.peek().tableMap.containsKey(pairs.getToken())) {
            Pairs error = new Pairs(Pairs.Kind.ERROR, "b");
            error.setLine(pairs.getLine());
            this.error.add(error);
        } else {
            tables.peek().addPair(pairs);
            for (Node i : node.getChildren()) {
                if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                    if (i.getPair().getKind().equals(Pairs.Kind.LBRACK)) {
                        pairs.setKind(Pairs.Kind.ARRAY_VAR);
                        pairs.setDim(pairs.getDim() + 1);
                    }
                } else {
                    if (i.getPair().getToken().equals("ConstExp")) {
                        buildTableExp(i);
                    } else if (i.getPair().getToken().equals("InitVal")) {
                        buildTable(i);
                    }
                }
            }
        }
    }

    public Pairs processLVal(Node node) {
        Pairs pairs = null;
        for (Node j : node.getChildren()) {
            if (j.getPair().getKind().equals(Pairs.Kind.IDENFR)) {
                pairs = containsIdent(j.getPair().getToken());
                if (pairs == null) {
                    Pairs error = new Pairs(Pairs.Kind.ERROR, "c");
                    error.setLine(j.getPair().getLine());
                    this.error.add(error);
                }
            } else if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                buildTableExp(j);
            }
        }
        return pairs;
    }

    public void buildTableStmt(Node node) {
        Pairs first = node.getChildren().get(0).getPair();
        if (first.getLine() == 530) {
            int flag = 1;
        }
        if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("LVal")) {
            if (node.getChildren().size() > 2 && node.getChildren().get(1).getPair().getKind().equals(Pairs.Kind.ASSIGN)) {
                Pairs temp = processLVal(node.getChildren().get(0));
                if (temp != null && (temp.getKind().equals(Pairs.Kind.VAL) ||
                        temp.getKind().equals(Pairs.Kind.ARRAY_VAL))) {
                    Pairs error = new Pairs(Pairs.Kind.ERROR, "h");
                    error.setLine(first.getLine());
                    this.error.add(error);
                }
            }
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Exp")) {
                    buildTableExp(i);
                }
            }
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("Exp")) {
            buildTableExp(node.getChildren().get(0));
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("Block")) {
            buildTable(node);
        } else if (first.getKind().equals(Pairs.Kind.WHILETK)) {
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Stmt")) {
                    if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.PARSE) && i.getChildren().get(0).getPair().getToken().equals("Block")) {
                        SymbolTable table = new SymbolTable();
                        table.setType("circle");
                        tables.push(table);
                        buildTable(i.getChildren().get(0));
                        /*if (i.getChildren().size() > 2) {
                            if (!i.getChildren().get(i.getChildren().size() - 2).getChildren().get(0).getPair().getKind().equals(Pairs.Kind.RETURNTK)) {
                                if (!tables.peek().isVoid() && !tables.peek().isSimple() && !tables.peek().isCircle()) {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                    error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                                    this.error.add(error);
                                }
                            }
                        } else if (i.getChildren().size() == 2) {
                            if (!tables.peek().isVoid() && !tables.peek().isSimple() && !tables.peek().isCircle()) {
                                Pairs error = new Pairs(Pairs.Kind.ERROR, "g");
                                error.setLine(i.getChildren().get(i.getChildren().size() - 1).getPair().getLine());
                                this.error.add(error);
                            }
                        }*/
                        tables.pop();
                    } else if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.BREAKTK) || i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.CONTINUETK)) {
                        continue;

                    } else {
                        buildTableStmt(i);
                    }
                } else {
                    buildTable(i);
                }
            }
        } else if (first.getKind().equals(Pairs.Kind.RETURNTK)) {
            if (node.getChildren().size() > 1) {
                if (node.getChildren().get(1).getPair().getKind().equals(Pairs.Kind.SEMICN)) {  //r ;
                    if (tables.peek().isInt()) {
                        Pairs error = new Pairs(Pairs.Kind.ERROR, "f");
                        error.setLine(first.getLine());
                        this.error.add(error);
                    }
                } else {                                                                        //r e ;
                    if (tables.peek().isVoid()) {
                        Pairs error = new Pairs(Pairs.Kind.ERROR, "f");
                        error.setLine(first.getLine());
                        this.error.add(error);
                    }
                }
            }
        } else if (first.getKind().equals(Pairs.Kind.PRINTFTK)) {
            int cnt1 = 0;
            int cnt2 = 0;
            int flag = 0;
            if (first.getLine() == 723) {
                flag = 0;
            }
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.STRCON)) {
                    String str = i.getPair().getToken();
                    for (int j = 1; j < str.length() - 1; j++) {
                        if (str.charAt(j) == '%') {
                            if (j != str.length() - 1 && str.charAt(j + 1) == 'd') {
                                cnt1++;
                            } else {
                                Pairs error = new Pairs(Pairs.Kind.ERROR, "a");
                                error.setLine(i.getPair().getLine());
                                this.error.add(error);
                                flag = 1;
                                break;
                            }
                        } else if (str.charAt(j) == 32 || str.charAt(j) == 33 || (str.charAt(j) >= 40 && str.charAt(j) <= 126)) {
                            if (str.charAt(j) == '\\') {
                                if (j != str.length() - 1 && str.charAt(j + 1) == 'n') {
                                    continue;
                                } else {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "a");
                                    error.setLine(i.getPair().getLine());
                                    this.error.add(error);
                                    flag = 1;
                                    break;
                                }
                            } else {
                                continue;
                            }
                        } else {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "a");
                            error.setLine(i.getPair().getLine());
                            this.error.add(error);
                            flag = 1;
                            break;
                        }
                    }
                } else {
                    if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Exp")) {
                        cnt2++;
                        buildTableExp(i);
                    }
                }
            }
            if (flag == 0 && cnt1 != cnt2) {
                Pairs error = new Pairs(Pairs.Kind.ERROR, "l");
                error.setLine(first.getLine());
                this.error.add(error);
            }
        } else {
            buildTable(node);
        }
    }

    public Pairs buildTableUnaryExp(Node node) {
        Pairs first = node.getChildren().get(0).getPair();
        if (first.getLine() == 529) {
            int flag = 1;
        }
        if (first.getKind().equals(Pairs.Kind.IDENFR)) {
            Pairs pairs = containsIdent(first.getToken());
            if (pairs == null) {
                Pairs error = new Pairs(Pairs.Kind.ERROR, "c");
                error.setLine(first.getLine());
                this.error.add(error);
            } else {
                if (first.getLine() == 455) {
                    int flag = 1;
                }
                ArrayList<Pairs> paramList = new ArrayList<>();
                int cnt = 0;
                for (Node i : node.getChildren()) {
                    if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("FuncRParams")) {
                        for (Node j : i.getChildren()) {
                            if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                                cnt++;
                                paramList.add(buildTableExp(j));
                            }
                        }
                        if (cnt != pairs.getParams().size()) {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "d");
                            error.setLine(first.getLine());
                            this.error.add(error);
                        } else {
                            if (first.getLine() == 529) {
                                int flag = 1;
                            }
                            for (int j = 0; j < cnt; j++) {
                                if (pairs.getParams().get(j).getType().equals(paramList.get(j).getType()) &&
                                        pairs.getParams().get(j).getDim() == paramList.get(j).getDim()) {
                                    if ((pairs.getParams().get(j).getKind().equals(Pairs.Kind.VAL) && paramList.get(j).getKind().equals(Pairs.Kind.VAL)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.VAL) && paramList.get(j).getKind().equals(Pairs.Kind.VAR)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.VAR) && paramList.get(j).getKind().equals(Pairs.Kind.VAL)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.VAR) && paramList.get(j).getKind().equals(Pairs.Kind.VAR)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.ARRAY_VAL) && paramList.get(j).getKind().equals(Pairs.Kind.ARRAY_VAL)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.ARRAY_VAR) && paramList.get(j).getKind().equals(Pairs.Kind.ARRAY_VAL)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.ARRAY_VAR) && paramList.get(j).getKind().equals(Pairs.Kind.ARRAY_VAR)) ||
                                            (pairs.getParams().get(j).getKind().equals(Pairs.Kind.ARRAY_VAL) && paramList.get(j).getKind().equals(Pairs.Kind.ARRAY_VAR)) ||
                                            paramList.get(j).getKind().equals(Pairs.Kind.FUNC)) {
                                        continue;
                                    } else {
                                        Pairs error = new Pairs(Pairs.Kind.ERROR, "e");
                                        error.setLine(first.getLine());
                                        this.error.add(error);
                                        break;
                                    }
                                } else {
                                    Pairs error = new Pairs(Pairs.Kind.ERROR, "e");
                                    error.setLine(first.getLine());
                                    this.error.add(error);
                                    break;
                                }
                            }
                        }
                    }
                }
                if (paramList.isEmpty()) {
                    if (pairs.getParams().size() != 0) {
                        Pairs error = new Pairs(Pairs.Kind.ERROR, "d");
                        error.setLine(first.getLine());
                        this.error.add(error);
                    }
                }
            }
            if (pairs == null) {
                return new Pairs(Pairs.Kind.VAL, "func", "int", first.getLine(), 0);
            } else {
                return new Pairs(pairs.getKind(), pairs.getToken(), pairs.getType(), pairs.getDim());
            }
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("UnaryOp")) {
            return buildTableExp(node.getChildren().get(1));
        } else {
            return buildTableExp(node.getChildren().get(0));
        }
    }

    public Pairs buildTableExp(Node i) {
        if (i.getPair().getToken().equals("Exp")) {
            return buildTableExp(i.getChildren().get(0));
        } else if (i.getPair().getToken().equals("PrimaryExp")) {
            if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.LPARENT)) {
                return buildTableExp(i.getChildren().get(1));
            } else if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.PARSE) && i.getChildren().get(0).getPair().getToken().equals("LVal")) {
                if (i.getChildren().get(0).getPair().getLine() == 154) {
                    int flag = 1;
                }
                Pairs pairs = null;
                //Pairs pairs = new Pairs(Pairs.Kind.VAR, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
                Pairs result = new Pairs(Pairs.Kind.VAL, i.getPair().getToken());
                for (Node j : i.getChildren().get(0).getChildren()) {
                    if (j.getPair().getKind().equals(Pairs.Kind.IDENFR)) {
                        pairs = containsIdent(j.getPair().getToken());
                        if (pairs == null) {
                            Pairs error = new Pairs(Pairs.Kind.ERROR, "c");
                            error.setLine(j.getPair().getLine());
                            this.error.add(error);
                            break;
                        } else {
                            result = new Pairs(pairs.getKind(), pairs.getToken(), pairs.getType(), pairs.getLine(), pairs.getDim());

                        }
                    } else if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                        if (result.getDim() == 2) {
                            result.setDim(result.getDim() - 1);
                        } else if (result.getDim() == 1) {
                            result.setDim(result.getDim() - 1);
                            result.setKind(Pairs.Kind.VAL);
                        }
                        buildTableExp(j);
                    }
                }
                return result;
            } else {
                return buildTableExp(i.getChildren().get(0));
            }
        } else if (i.getPair().getToken().equals("UnaryExp")) {
            if (i.getPair().getLine() == 1) {
                int flag = 1;
            }
            return buildTableUnaryExp(i);
        } else if (i.getPair().getToken().equals("Number")) {
            return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
        } else if (i.getPair().getToken().equals("MulExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("AddExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("RelExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("EqExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("LAndExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("LOrExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    buildTableExp(j);
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("ConstExp")) {
            return buildTableExp(i.getChildren().get(0));
        }
        return null;

    }
}
